#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
配置缓存与管理机制模块
负责管理编码类目配置的缓存、提供快速访问接口
"""

from typing import Dict, Any, Optional
import threading
import time
from .category_parser import CategoryConfigParser


class CategoryConfigManager:
    """
    编码类目配置管理器
    提供配置的缓存、快速访问和管理功能
    """
    
    def __init__(self):
        """
        初始化配置管理器
        """
        # 配置缓存
        self._config_cache: Dict[str, Any] = {}
        # 配置文件路径
        self._config_file_path: Optional[str] = None
        # 上次加载时间
        self._last_loaded_time: float = 0
        # 解析器实例
        self._parser = CategoryConfigParser()
        # 线程锁，保证线程安全
        self._lock = threading.RLock()
    
    def load_config(self, file_path: str) -> Dict[str, Any]:
        """
        加载配置文件
        
        Args:
            file_path: 配置文件路径
            
        Returns:
            加载的配置字典
            
        Raises:
            Exception: 加载或验证失败时抛出异常
        """
        with self._lock:
            self._config_file_path = file_path
            self._config_cache = self._parser.parse_file(file_path)
            
            # 验证配置
            is_valid, errors = self._parser.validate_config(self._config_cache)
            if not is_valid:
                error_msg = "配置验证失败:\n" + "\n".join([f"  - {error}" for error in errors])
                raise ValueError(error_msg)
            
            self._last_loaded_time = time.time()
            return self._config_cache
    
    def get_config(self) -> Dict[str, Any]:
        """
        获取当前缓存的配置
        
        Returns:
            配置字典
            
        Raises:
            RuntimeError: 如果配置尚未加载
        """
        with self._lock:
            if not self._config_cache:
                raise RuntimeError("配置尚未加载，请先调用load_config方法")
            return self._config_cache
    
    def get_category(self, category_name: str) -> Optional[Dict[str, Any]]:
        """
        获取特定类目配置
        
        Args:
            category_name: 类目名称
            
        Returns:
            类目配置字典，如果不存在返回None
        """
        with self._lock:
            return self._config_cache.get(category_name)
    
    def get_required_categories(self) -> Dict[str, Dict[str, Any]]:
        """
        获取所有必填类目
        
        Returns:
            必填类目字典，键为类目名称，值为类目配置
        """
        with self._lock:
            return {
                name: data for name, data in self._config_cache.items()
                if data.get('required', False)
            }


    def get_category_options(self, category_name: str) -> Optional[Dict[str, Dict[str, Any]]]:
        """
        获取特定类目下的所有选项
        
        Args:
            category_name: 类目名称
            
        Returns:
            选项字典，如果类目不存在返回None
        """
        with self._lock:
            category = self._config_cache.get(category_name)
            return category.get('options') if category else None
    
    def get_option_keywords(self, category_name: str, option_name: str) -> Optional[list]:
        """
        获取特定选项的关键词列表
        
        Args:
            category_name: 类目名称
            option_name: 选项名称
            
        Returns:
            关键词列表，如果类目或选项不存在返回None
        """
        with self._lock:
            category = self._config_cache.get(category_name)
            if not category:
                return None
            
            option = category.get('options', {}).get(option_name)
            return option.get('keywords') if option else None
    
    def is_category_required(self, category_name: str) -> bool:
        """
        检查类目是否为必填
        
        Args:
            category_name: 类目名称
            
        Returns:
            是否为必填类目
        """
        with self._lock:
            category = self._config_cache.get(category_name)
            return category.get('required', False) if category else False
    
    def get_categories_count(self) -> int:
        """
        获取类目总数
        
        Returns:
            类目数量
        """
        with self._lock:
            return len(self._config_cache)
    
    def get_last_loaded_time(self) -> float:
        """
        获取上次加载配置的时间戳
        
        Returns:
            时间戳
        """
        with self._lock:
            return self._last_loaded_time
    
    def is_config_loaded(self) -> bool:
        """
        检查配置是否已加载
        
        Returns:
            是否已加载配置
        """
        with self._lock:
            return bool(self._config_cache)


# 创建全局单例实例
global_config_manager = CategoryConfigManager()
category_config_manager = global_config_manager  # 保持兼容性的别名


# 使用示例
if __name__ == '__main__':
    try:
        # 创建管理器实例
        manager = CategoryConfigManager()
        
        # 加载配置
        print("加载配置文件...")
        config = manager.load_config("../../data/编码类目表.txt")
        print(f"配置加载成功，包含 {manager.get_categories_count()} 个类目")
        
        # 获取必填类目
        required_categories = manager.get_required_categories()
        print(f"必填类目数量: {len(required_categories)}")
        print(f"必填类目列表: {', '.join(required_categories.keys())}")
        
        # 获取特定类目信息
        if '场景设定' in config:
            scene_category = manager.get_category('场景设定')
            print(f"\n'场景设定'类目信息:")
            print(f"  必填: {manager.is_category_required('场景设定')}")
            print(f"  选项数: {len(scene_category['options'])}")
            
            # 获取选项关键词
            if '校园场景' in scene_category['options']:
                keywords = manager.get_option_keywords('场景设定', '校园场景')
                print(f"  '校园场景'选项的关键词: {', '.join(keywords[:3])}...")
        
        print("\n配置管理功能测试成功!")
        
    except Exception as e:
        print(f"测试失败: {str(e)}")